package com.education.ai.service.impl;

import com.education.ai.service.AiTeachingService;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * AI教学服务实现类，处理与AI模型交互的逻辑
 */
@Service
public class AiTeachingServiceImpl extends AiTeachingService {
    
    private static final Logger logger = LoggerFactory.getLogger(AiTeachingServiceImpl.class);
    
    @Value("${tongyi.qwen.api.key:your-api-key-here}")
    private String apiKey;

    @Value("${tongyi.qwen.api.uri:https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation}")
    private String apiEndpoint;

    @Value("${tongyi.qwen.api.model:qwen-max}")
    private String model;
    
    private final RestTemplate restTemplate = new RestTemplate();
    
    /**
     * 分析学生学习水平
     * 
     * @param studentId 学生ID
     * @param subject 学科
     * @param question 学生提问的问题
     * @param performance 学生的学习表现数据
     * @return 分析结果
     */
    @SuppressWarnings("unchecked")
    @Override
    public String analyzeStudentLevel(String studentId, String subject, String question, Map<String, Object> performance) {
        try {
            logger.info("开始分析学生[{}]的[{}]学科学习水平，附加数据：{}", studentId, subject, performance);
            
            StringBuilder promptBuilder = new StringBuilder();
            
            // 基础提示词
            promptBuilder.append(String.format("请分析学生%s在%s科目的学习情况", studentId, subject));
            
            // 添加学生提问的问题（如果有）
            if (question != null && !question.trim().isEmpty()) {
                promptBuilder.append(String.format("，并回答学生的问题：%s", question));
                logger.info("学生提出的问题: {}", question);
            }
            
            promptBuilder.append("。");
            
            // 添加学习表现数据（如果有）
            if (performance != null && !performance.isEmpty()) {
                logger.info("学生提供了学习表现数据，包含 {} 个字段: {}", 
                        performance.keySet().size(), performance.keySet());
                promptBuilder.append("\n\n学生的学习数据如下：\n");
                
                // 添加平均分
                if (performance.containsKey("averageScore")) {
                    Object scoreValue = performance.get("averageScore");
                    promptBuilder.append(String.format("- 平均分：%s\n", scoreValue));
                    logger.info("学生平均分: {}", scoreValue);
                } else {
                    logger.warn("学习数据中缺少平均分字段");
                }
                
                // 添加完成的练习数量
                if (performance.containsKey("completedExercises")) {
                    Object exercisesValue = performance.get("completedExercises");
                    promptBuilder.append(String.format("- 已完成练习数量：%s\n", exercisesValue));
                    logger.info("学生已完成练习数量: {}", exercisesValue);
                } else {
                    logger.warn("学习数据中缺少已完成练习数量字段");
                }
                
                // 添加学习时长
                if (performance.containsKey("studyTime")) {
                    Object timeValue = performance.get("studyTime");
                    promptBuilder.append(String.format("- 学习时长：%s分钟\n", timeValue));
                    logger.info("学生学习时长: {}分钟", timeValue);
                } else {
                    logger.warn("学习数据中缺少学习时长字段");
                }
                
                // 添加错题数量
                if (performance.containsKey("mistakeCount")) {
                    Object mistakeValue = performance.get("mistakeCount");
                    promptBuilder.append(String.format("- 错题数量：%s\n", mistakeValue));
                    logger.info("学生错题数量: {}", mistakeValue);
                } else {
                    logger.warn("学习数据中缺少错题数量字段");
                }
                
                // 添加最近练习情况
                if (performance.containsKey("recentPractices") && performance.get("recentPractices") instanceof List) {
                    List<?> practices = (List<?>) performance.get("recentPractices");
                    if (!practices.isEmpty()) {
                        logger.info("学生有 {} 条最近练习记录", practices.size());
                        promptBuilder.append("- 最近练习情况：\n");
                        int count = 0;
                        for (Object practice : practices) {
                            if (count++ >= 5) break; // 最多显示5条
                            if (practice instanceof Map) {
                                Map<String, Object> practiceMap = (Map<String, Object>) practice;
                                String date = String.valueOf(practiceMap.getOrDefault("date", "未知日期"));
                                String topic = String.valueOf(practiceMap.getOrDefault("topic", "未知主题"));
                                String score = String.valueOf(practiceMap.getOrDefault("score", "未知分数"));
                                promptBuilder.append(String.format("  * %s：%s，得分：%s\n", date, topic, score));
                            }
                        }
                    } else {
                        logger.warn("学生没有最近的练习记录");
                    }
                } else {
                    logger.warn("学习数据中缺少recentPractices字段或格式不正确");
                }
                
                // 添加学习进度
                if (performance.containsKey("progress")) {
                    Object progressValue = performance.get("progress");
                    promptBuilder.append(String.format("- 课程进度：%s%%\n", progressValue));
                    logger.info("学生课程进度: {}%", progressValue);
                }
                
                // 分析要点提示
                promptBuilder.append("\n请根据以上数据，进行全面分析，包括：\n");
                promptBuilder.append("1. 知识掌握程度\n");
                promptBuilder.append("2. 学习态度与习惯\n");
                promptBuilder.append("3. 应用能力表现\n");
                promptBuilder.append("4. 针对性学习建议\n");
                
                // 如果是物理学科，添加特定提示
                if ("物理".equals(subject)) {
                    promptBuilder.append("\n对于物理学科，请额外关注以下方面：\n");
                    promptBuilder.append("1. 对物理定律的理解和运用能力\n");
                    promptBuilder.append("2. 解决实际问题的能力\n");
                    promptBuilder.append("3. 实验设计和数据分析能力\n");
                    promptBuilder.append("\n可以结合牛顿运动定律、能量守恒等基本物理原理进行分析。\n");
                }
            } else {
                // 没有额外数据时的基础提示
                logger.warn("没有提供学生学习表现数据，使用基础提示");
                promptBuilder.append("\n\n请分析包括知识掌握度、学习积极性、应用能力以及针对性建议。");
                
                // 如果是物理学科，添加特定提示
                if ("物理".equals(subject)) {
                    promptBuilder.append("\n\n对于物理学科，请结合基础物理学知识，如牛顿运动定律、能量守恒等基本原理进行回答。");
                }
            }
            
            String prompt = promptBuilder.toString();
            logger.info("生成的完整提示词: {}", prompt);
            
            // 创建输入对象 - 直接使用prompt而非messages
            Map<String, Object> input = new HashMap<>();
            input.put("prompt", prompt);
            
            // 创建参数对象
            Map<String, Object> parameters = new HashMap<>();
            parameters.put("temperature", 0.7);
            parameters.put("max_tokens", 1500);  // 增加最大tokens以获取更完整回复
            
            // 创建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("model", model);  // 使用配置的模型名称
            requestBody.put("input", input);
            requestBody.put("parameters", parameters);
            
            logger.info("发送学生水平分析请求到千问API");
            
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + apiKey);
            
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
            
            ResponseEntity<String> response = restTemplate.exchange(
                apiEndpoint,
                HttpMethod.POST,
                requestEntity,
                String.class
            );
            
            String responseJson = response.getBody();
            logger.info("收到千问API响应，长度: {}", responseJson != null ? responseJson.length() : 0);
            
            if (responseJson != null) {
                try {
                    ObjectMapper mapper = new ObjectMapper();
                    Map<String, Object> responseMap = mapper.readValue(responseJson, Map.class);
                    
                    if (responseMap.containsKey("output") && responseMap.get("output") instanceof Map) {
                        Map<String, Object> output = (Map<String, Object>) responseMap.get("output");
                        if (output.containsKey("text")) {
                            String analysisText = (String) output.get("text");
                            logger.info("成功解析AI分析结果，文本长度: {}", analysisText.length());
                            return analysisText;
                        }
                    }
                    
                    logger.error("API响应格式异常: {}", responseMap);
                    return "无法从API响应中获取分析结果。请稍后再试。";
                } catch (Exception e) {
                    logger.error("解析API响应失败: {}", e.getMessage(), e);
                    return "解析API响应时出错: " + e.getMessage();
                }
            } else {
                logger.error("API响应为空");
                return "API响应为空，请稍后再试。";
            }
        } catch (Exception e) {
            logger.error("分析学生水平时发生异常: {}", e.getMessage(), e);
            return "分析学生水平失败: " + (e.getMessage() != null ? e.getMessage() : "未知错误");
        }
    }
    
    /**
     * 生成学习能力评估
     * 
     * @param studentId 学生ID
     * @param subject 学科
     * @return 能力评估数据
     */
    @SuppressWarnings("unchecked")
    @Override
    public Map<String, Object> generateAbilityAssessment(String studentId, String subject) {
        try {
            String prompt = String.format(
                "请对学生ID为%s的%s学科能力进行详细评估，评估维度包括：\n" +
                "1. 知识维度：对基础概念和理论的理解程度\n" +
                "2. 应用维度：将知识应用到实际问题的能力\n" +
                "3. 创新维度：创新思维和解决问题的独特性\n\n" +
                "请给出以下评估内容：\n" +
                "1. 各维度的评分（满分10分）\n" +
                "2. 详细评估分析\n" +
                "3. 针对性改进建议\n\n" +
                "请按照以下JSON格式返回结果：\n" +
                "{\n" +
                "  \"knowledge_dimension\": 评分（浮点数，0-10）,\n" +
                "  \"application_dimension\": 评分（浮点数，0-10）,\n" +
                "  \"innovation_dimension\": 评分（浮点数，0-10）,\n" +
                "  \"assessment_details\": \"详细评估分析内容\",\n" +
                "  \"recommendation\": \"针对性改进建议\"\n" +
                "}",
                studentId, subject);
            
            logger.info("生成能力评估的提示词: {}", prompt);
            
            // 创建输入对象
            Map<String, Object> input = new HashMap<>();
            input.put("prompt", prompt);
            
            // 创建参数对象
            Map<String, Object> parameters = new HashMap<>();
            parameters.put("temperature", 0.7);
            
            // 创建响应格式对象
            Map<String, String> responseFormat = new HashMap<>();
            responseFormat.put("type", "json_object");
            parameters.put("response_format", responseFormat);
            
            // 创建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("model", model);
            requestBody.put("input", input);
            requestBody.put("parameters", parameters);
            
            logger.info("发送到千问API的请求: {}", requestBody);
            
            // 发送请求到千问API
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + apiKey);
            
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
            
            ResponseEntity<String> response = restTemplate.exchange(
                apiEndpoint,
                HttpMethod.POST,
                requestEntity,
                String.class
            );
            
            String responseBody = response.getBody();
            logger.info("千问API原始响应: {}", responseBody);
            
            ObjectMapper mapper = new ObjectMapper();
            Map<String, Object> responseMap = mapper.readValue(responseBody, Map.class);
            
            if (responseMap.containsKey("output") && responseMap.get("output") instanceof Map) {
                Map<String, Object> output = (Map<String, Object>) responseMap.get("output");
                if (output.containsKey("text")) {
                    String jsonText = (String) output.get("text");
                    logger.info("千问API返回的JSON文本: {}", jsonText);
                    
                    try {
                        // 解析返回的JSON文本
                        Map<String, Object> assessmentData = mapper.readValue(jsonText, Map.class);
                        logger.info("解析后的能力评估数据: {}", assessmentData);
                        
                        // 确保所有必要的字段都存在
                        ensureAbilityFieldsExist(assessmentData);
                        
                        return assessmentData;
                    } catch (Exception e) {
                        logger.error("解析千问API返回的JSON失败: {}", e.getMessage(), e);
                        // 返回一个带有错误信息的结果
                        Map<String, Object> errorResult = new HashMap<>();
                        errorResult.put("error", "解析评估数据失败");
                        errorResult.put("assessment_details", "解析千问API返回的JSON时出错: " + e.getMessage());
                        errorResult.put("knowledge_dimension", 8.5);
                        errorResult.put("application_dimension", 7.2);
                        errorResult.put("innovation_dimension", 6.8);
                        errorResult.put("recommendation", "由于系统错误，无法获取个性化建议。请继续努力学习，关注基础知识和应用能力的提升。");
                        return errorResult;
                    }
                }
            }
            
            logger.error("千问API响应格式异常: {}", responseMap);
            Map<String, Object> errorResult = new HashMap<>();
            errorResult.put("error", "API响应格式异常");
            errorResult.put("assessment_details", "千问API返回的数据格式不符合预期");
            
            // 为了让前端能正确显示，添加默认值
            errorResult.put("knowledge_dimension", 8.5); // 默认值
            errorResult.put("application_dimension", 7.2); // 默认值
            errorResult.put("innovation_dimension", 6.8); // 默认值
            errorResult.put("recommendation", "由于系统错误，无法获取个性化建议。请继续努力学习，关注基础知识和应用能力的提升。");
            
            return errorResult;
        } catch (Exception e) {
            logger.error("调用千问API失败: {}", e.getMessage(), e);
            Map<String, Object> errorResult = new HashMap<>();
            errorResult.put("error", "AI评估失败");
            errorResult.put("assessment_details", "调用千问API时出错: " + e.getMessage());
            
            // 为了让前端能正确显示，添加默认值
            errorResult.put("knowledge_dimension", 8.5); // 默认值
            errorResult.put("application_dimension", 7.2); // 默认值
            errorResult.put("innovation_dimension", 6.8); // 默认值
            errorResult.put("recommendation", "由于系统错误，无法获取个性化建议。请继续努力学习，关注基础知识和应用能力的提升。");
            
            return errorResult;
        }
    }
    
    /**
     * 确保能力评估字段存在
     */
    private void ensureAbilityFieldsExist(Map<String, Object> assessmentData) {
        // 确保三个维度的评分字段存在
        if (!assessmentData.containsKey("knowledge_dimension")) {
            assessmentData.put("knowledge_dimension", 7.5);
            logger.warn("能力评估结果中缺少knowledge_dimension字段，已添加默认值7.5");
        }
        
        if (!assessmentData.containsKey("application_dimension")) {
            assessmentData.put("application_dimension", 7.0);
            logger.warn("能力评估结果中缺少application_dimension字段，已添加默认值7.0");
        }
        
        if (!assessmentData.containsKey("innovation_dimension")) {
            assessmentData.put("innovation_dimension", 6.5);
            logger.warn("能力评估结果中缺少innovation_dimension字段，已添加默认值6.5");
        }
        
        // 确保评估详情和建议字段存在
        if (!assessmentData.containsKey("assessment_details")) {
            assessmentData.put("assessment_details", "无法获取详细评估分析。");
            logger.warn("能力评估结果中缺少assessment_details字段，已添加默认值");
        }
        
        if (!assessmentData.containsKey("recommendation")) {
            assessmentData.put("recommendation", "无法获取针对性改进建议。");
            logger.warn("能力评估结果中缺少recommendation字段，已添加默认值");
        }
    }
} 